# 下一页
# 当下一页卡死10次时, 使用鼠标点击右箭头按钮的方式翻页
# 当第一个右箭头按钮没找到, 找另一个
# 当有跳过无数据区的需求时, 就不使用下一页, 改用输入数字的方式


import os
import time
import cv2
import numpy as np
import pyautogui
import logging

from shape_judgment.screen_region_storage import get_region_pos_only,get_button_cention,storage_a_region_pos_only


ALOW_TIME = 3

retry_times = 0
last_stock_id = ""


# 可能会有多个匹配, 返回所有匹配先
def find_all_matches(screen_img, template_img, threshold):
    """获取所有符合阈值的匹配结果，返回列表[(x, y, w, h, 匹配度)]"""

    h, w = template_img.shape[:2]
    
    if h == 0 or w == 0:
        return []
    
    if screen_img.size < template_img.size:  # 截图尺寸小于模板尺寸
        print("截图尺寸小于模板尺寸")
        return []
    
    # 执行模板匹配并获取匹配度矩阵
    result = cv2.matchTemplate(
        screen_img, 
        template_img, 
        cv2.TM_CCOEFF_NORMED
    )
    # 找到所有超过阈值的位置
    locations = np.where(result >= threshold)
    matches = []
    
    # 遍历所有匹配位置，记录坐标和匹配度
    for y, x in zip(locations[0], locations[1]):
        match_value = result[y, x]  # 该位置的匹配度（0-1）
        matches.append((x, y, w, h, match_value))  # 存储x坐标、y坐标、宽、高、匹配度
    return matches
# 找 模板匹配
def find_template_position(screen_img, template_img, threshold=0.85):
    """
    在屏幕截图中查找模板位置
    :param screen_img: 全屏截图（BGR格式）
    :param template_img: 模板图片（BGR格式）
    :param threshold: 匹配阈值（0-1，越高越严格） 数值为0.8时,还是会有错误, 比如需匹配0.00%,匹配到的却是0.05%
    :return: 匹配区域的左上角坐标(x, y)，若未找到返回None
    """
    
    all_matches  = find_all_matches(screen_img, template_img,threshold)
    if not all_matches:
        return None  # 无匹配结果
    # 按X坐标升序排序（X越小越靠左），取第一个
    # 若X相同，可选匹配度最高的
    all_matches.sort(key=lambda m: (-m[4]))  # 优先按X排序，再按y排序 找到左上角的一个叉按钮
    rightmost = all_matches[0]
    return (rightmost[0], rightmost[1], rightmost[2], rightmost[3])  # 返回(x, y, w, h)


window_pos_x=0
window_pos_y=0
window_width=0

def set_window_pos_73(x,y):
    global window_pos_x
    global window_pos_y
    window_pos_x = x
    window_pos_y = y


def click_button(pos_x, pos_y):
    """
    模拟鼠标点击按钮
    
    参数:
    pos_x -- 按钮左上角x坐标
    pos_y -- 按钮左上角y坐标
    width -- 按钮宽度
    height -- 按钮高度
    """
    
    # 移动鼠标到按钮中心
    pyautogui.moveTo(pos_x+window_pos_x, pos_y+window_pos_y, duration=0.0)  # duration控制移动速度，单位秒
    # 点击鼠标左键
    pyautogui.click()
    time.sleep(0.01)
    
    # 点击后, 把鼠标移到最右, 以防止高亮造成下去的图像比对失败
    pyautogui.moveTo(window_width+window_pos_x, pos_y+window_pos_y, duration=0.0)


# K线图按钮模板 已按下的状态:
template_k_line_button_pushed = cv2.imread("eastmoney desktop software picture/button_k_line_pushed.png")

# K线图按钮模板 未按下的状态:
template_k_line_button_idle = cv2.imread("eastmoney desktop software picture/button_k_line_idle.png")

# 判断K线按钮是否已经按下
def is_k_line_button_activied(frame):
    # 取截屏的前40像素:
    img_left_40_of_screen = frame[:,0:40]
    # 取匹配的坐标:
    pos = find_template_position(img_left_40_of_screen, template_k_line_button_pushed)
    return pos != None


# 点击K线按钮
def click_k_line_button(frame):
    # 取截屏的前40像素:
    img_left_40_of_screen = frame[:,0:40]
    # 取匹配的坐标:
    pos = find_template_position(img_left_40_of_screen, template_k_line_button_idle)
    if pos != None: # 按钮已经按下
        click_button(pos[0]+14, pos[1]+14)
    else: # 按钮没有按下
        cv2.imwrite("get_F10_data_k_line_button_not_found_1.png", img_left_40_of_screen)
        # cv2.imwrite("get_F10_data_k_line_button_not_found_2.png", self.template_k_line_button_idle) # 模板一般不会出问题.
        raise Exception("!!!! ERR 129 K线按钮没找到, 没有K线按钮按下的情况才去找K线按钮的")

def page_down(stock_id,no_data_area,screen_shot_img):
    # 当有跳过无数据区的需求时, 就不使用下一页, 改用输入数字的方式

    global retry_times,last_stock_id

    logging.info(f"page_down BEGIN stock_id: {stock_id}")
    if(stock_id == last_stock_id):
        retry_times-=1   
        logging.info(f"page_down # 112  retry_times: {retry_times}") 
    else:
        retry_times = ALOW_TIME
        last_stock_id = stock_id
        logging.info(f"page_down # 116") 
    # 之前的翻页不管用 使用其它方式来翻页:
    if(retry_times<=0):
        logging.info(f"page_down # 119") 
        # 0. 保证是在K线图页面
        bool_is_restored = is_k_line_button_activied()
        if False == bool_is_restored:
            click_k_line_button()
            logging.info(f"page_down # 151") 

        # 1. 点击右箭头按钮
        # 1.1 点击右侧边栏1的按钮
        # 取侧边栏1的按钮图像, 通过图像比对, 看是不是按钮:
        button_pos_1 = get_region_pos_only("右箭头按钮1")
        if(button_pos_1 is None): raise Exception("没有找到右箭头按钮1的坐标")
        logging.info(f"page_down # 127 右箭头坐标:{button_pos_1}") 
        # 1.1.1 找右侧边栏1的按钮是否匹配按钮图像
        x1,x2,y1,y2 = button_pos_1
        img_button_1 = screen_shot_img[y1:y2,x1:x2]
        template_img_right = cv2.imread("eastmoney desktop software picture/template_triangle_button_right.png")
        pos_test_41 = find_template_position(img_button_1, template_img_right)
        global window_width
        window_height,window_width =  screen_shot_img.shape[:2]
        # 1.1.2 如果匹配, 则点击
        if(pos_test_41 is not None):
            x,y = get_button_cention("右箭头按钮1")
            click_button(x,y)
            return
        # 1.2 如果不存在右侧边栏1的按钮, 则点击右侧边栏2的按钮
        else:
            button_pos_2 = get_region_pos_only("右箭头按钮2")
            if(button_pos_2 is not None):
                # 比对图像, 看是否匹配
                x1,x2,y1,y2 = button_pos_2
                img_button_1 = screen_shot_img[y1:y2,x1:x2]
                pos_test_130 = find_template_position(img_button_1, template_img_right)
                if(pos_test_130 is None):
                    cv2.imwrite(f"out_put_crash_screen_shot.png", screen_shot_img)
                    cv2.imwrite(f"out_put_crash_screen_shot_2.png", img_button_1)
                    raise Exception(f"!!!!    ERR 134 没有找到右箭头按钮2的的匹配图像 {x1,x2,y1,y2}\t已保存崩溃时的截图")
                else:
                    x,y = get_button_cention("右箭头按钮2")
                    click_button(x,y)
                    return
            else:
                # 1.2.1 如果右侧边栏2的按钮原本不存在, 则找右侧边栏的按钮, 并存其坐标
                pos_test_140 = find_template_position(screen_shot_img, template_img_right)
                if pos_test_140 is None:
                    raise Exception("!!!!    ERR 142 没有找到右箭头按钮2的坐标")
                pos_x,pos_y,width,height = pos_test_140
                x1 = pos_x
                x2 = pos_x+width
                y1 = pos_y
                y2 = pos_y+height
                # 保存 右箭头按钮2 (唯一一次)
                storage_a_region_pos_only(x1,x2,y1,y2,"右箭头按钮2")
                # 1.2.2 点击
                x,y = get_button_cention("右箭头按钮2")
                click_button(x,y)
                return

    
    # 判断是否跳过无数据区
    if(not no_data_area.is_start_of_no_data_area(stock_id)):
        pyautogui.press('pagedown')
        logging.info(f"page_down END Final") 





#[MISSION]记录下一个箭头的坐标, 单单记录坐标, 不裁剪图片
#	[MISSION]另开一个字典来存按钮坐标	[C]
#	[MISSION]存坐标[C]
#		def storage_a_region_pos_only(x1,x2,y1,y2,name):
#		    global storage_region_pos_only
#		    storage_region_pos_only[name] = [x1,x2,y1,y2]
#	[MISSION]取坐标[C]
#		def get_region_pos_only(name):
#		    global storage_region_pos_only
#		    return storage_region_pos_only[name]
#	[MISSION]在统一的界面切分函数中, screen_shot_split.py, 找出按钮的位置并存储
#		"右箭头按钮1"		
#	[MISSION]取按钮的中心, 以免误操作	
#		def get_button_cention(name):
#	这里有个问题: 右箭头按钮 可能在第二侧边栏的位置
#		这取决于有没有交易按钮
#		按钮一向会有, 找, 直到找到为止
#		不对, 最开始的查找功能, 只能找一个右箭头位置, 因为同一时间只有一种界面样式.
#[MISSION]建一个模块, pagedown.py [completed]
#
#[MISSION]点击[下一个]按钮
#	[MISSION]判断卡死[completed]
#		[MISSION]设置一个全局变量, 用于存卡死的次数, 以判断卡死, 暂先定义10次为卡死.
#		if(retry_times<=0)
#	[MISSION]没有第二侧边栏的"股票",也去取"股票"ID,不然没法判断是否卡死.
#		[MISSION]为了极致速度, 需要另外计算出一种坐标, 正好是原本第二侧边栏的坐标, 再用第一侧边栏的"股票名称与价格"区域的Y坐标去裁剪.
#
#--------
#038036 这只股票可以作为参考
#--------
#
#另外, 鼠标滚轮方面, 在没有切窗口的状态下, 也是能操作的, 只要鼠标指在东方财富窗口上.
#
#--------
#另一个问题: 由于鼠标移上右箭头按钮后, 按钮会变色,所以定位只能定一次.
#第一次鼠标定位是定到筹码按钮, 所以这问题应该还不会触发.
#--------
#
#[MISSION]传递窗口位置 传给pagedown模块[completed]
#	from shape_judgment.pagedown import page_down,set_window_pos_73
#
#[MISSION]上层调用的retry_times还得在上层处理 之前的retry_times的意义不一样, 是重试获取数据, 而不是重试pagedown
#	
#
#"右箭头按钮2"
#
#[MISSION]另一套取股票ID的函数[completed]
#	已证实, 没有侧边栏2的情况下, 股票ID所在的区域与之前是一样的.
#	x坐标的偏移是: 把区域顶到最右边, 然后往左缩两像素
#	[M]建一个函数 get_stock_id_334[completed]
#		函数里接收screen_shot_img作为参数
#	[M]计算小区域[completed]
#	[M]从小区域中, 取得股票ID
#	
#[MISSION]在上层调用, 在各股票运算之前, 就去取股票ID. 为了无数据区的收录.[completed]
#	因为没有筹码按钮的区域, 也要被当作无数据.
#            stock_id = get_stock_id( result_clips["股票名称与价格"]) 
#            stock_id = get_stock_id( result_clips["股票名称与价格"])
#	
#[MISSION]清除主逻辑中的 'pagedown' [completed]
#	一共有5处 , 看起来, 单单替换掉就可以
#	is_start_of_no_data_area 就一处, 今天主要是把这一个if语句干掉, 并做一个界面方面的防范
#	page_down(stock_id,self.no_data_area,frame)
#	
#	1:
#            # if(not self.no_data_area.is_start_of_no_data_area(stock_id)):
#            #     self.no_data_area.record_still_have_data_area(stock_id)
#            #     pyautogui.press('pagedown')
#            #     self.retry_times = 3
#            # else:
#            #     logging.info(f"# 321 {stock_id} 跳过 无数据区")
#    
#	2:
#	        if(not bool_is_have_button_trade):
#            # 没有交易按钮, 跳过
#            # print("# 272 没有交易按钮, 跳过")
#            self.no_data_area.record_none_data_state()
#            page_down(stock_id,self.no_data_area,frame)
#            return debug_frame
#	3:
#	        # return debug_frame # 至此, 用时0.05秒
#	        if(bool_is_delist or bool_is_unlisted):
#	            pyautogui.press('pagedown')
#	            time.sleep(0.1)
#	            return debug_frame
#	4,5:
#	        else:
#	            print("# 337 该股无数据")
#	            bool_have_button_chip = is_have_button_chip(result_clips["筹码按钮所在的菜单栏"])
#	            if(False == bool_have_button_chip):
#	                # 开发过程中, 记录调试信息 ",无筹码按钮_无筹码数据"
#	                # file_path = os.path.join(folder_path, 'chip_' + formatted_date + '.csv')
#	                # write_line_to_file(file_path,
#	                #                    stock_id+",无筹码按钮_无筹码数据")
#	                self.no_data_area.record_none_data_state()
#	                page_down(stock_id,self.no_data_area,frame)
#	                self.retry_times = 3
#	                time.sleep(0.1)
#	            else:
#	                # 有筹码按钮, 却没有数据
#	                file_path = os.path.join(folder_path, 'chip_' + formatted_date + '.csv')
#	                # write_line_to_file(file_path,
#	                #                    stock_id+",有筹码按钮_但无筹码数据")
#	                self.no_data_area.record_none_data_state()
#	                pyautogui.press('pagedown')
#	                self.retry_times = 3
#	                time.sleep(0.1)
#	[STOP]在上层逻辑重试的过程中, 不算没数据, 可能是还没刷新出来[但也没调用pagedown]
#
#[MISSION]在一些 pagedown 调用, 一并执行record_still_have_data_area, 否则就执行record_none_data_state() [completed]
	
# 2025-11-03
#    遍历到了751001这只股票. 但正常执行下来并不会遍历到这只.
#    解决办法是7开头的股票全跳过. 在no_data_area.py处理







